﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using ProjectBase.Core;
using Survey.Common;
using Survey.Common.Business;
using Survey.Common.Data;
using Survey.Entity;

namespace Survey.Business
{
    /// <summary>
    /// All Business checks for 'Question' on CRUD operations
    /// are nested and encapsulated in this QuestionFacade
    /// </summary>
    public class QuestionFacade : BaseFacade<Question, int, QuestionFilter, IQuestionDao>, IQuestionFacade
    {
        #region IBaseFacade<T> override - FACTORY METHOD

        /// <summary>
        /// Factory Method pattern.
        /// A central and only point for creating new entity of the type Question.
        /// </summary>
        /// <returns>new entity 'Question' transient</returns>
        public override Question CreateNew()
        {
            var entity = new Question
            {
                ValidUntil = DateTime.Now.Date.AddDays(7),
                Title = string.Empty,
                Description = string.Empty
            };
            return entity;
        }

        public virtual Answer CreateNewAnswer(Question question)
        {
            var item = new Answer
            {
                Question = question,
                Title = string.Empty,
                Description = string.Empty
            };

            return item;
        }

        /// <summary>
        /// Needed for the BaseFacade checks on Update() and Delete().
        /// </summary>
        /// <returns></returns>
        public override QuestionFilter CreateNewFilter()
        {
            var filter = base.CreateNewFilter();
            return filter;
        }

        #endregion IBaseFacade<T> override - FACTORY METHOD

        #region IQuestionFacade

        public override bool BindEntity(Question entity, IValueProvider valueProvider, string prefix = null, IEnumerable<string> includeProperties = null, IEnumerable<string> excludeProperties = null)
        {
            var result = base.BindEntity(entity, valueProvider, prefix, includeProperties, excludeProperties);
            result &= BindAnswers(entity, valueProvider, prefix.Extend("Answer"));

            return result;
        }

        protected virtual bool BindAnswers(Question entity, IValueProvider valueProvider, string prefix)
        {
            var objectBinder = new ListItemsBindingObject();
            Binder.Bind(objectBinder, valueProvider, prefix);

            // bind existing answers
            foreach (var answer in entity.Answers)
            {
                Binder.Bind(answer, valueProvider, prefix.Extend(answer.Position.ToString()));
            }

            // new IDs
            var newIDs = objectBinder.ExistingIDs
                .Where(index => index >= entity.Answers.Count);

            foreach (var newID in newIDs)
            {
                var answer = CreateNewAnswer(entity);
                Binder.Bind(answer, valueProvider, prefix.Extend(newID.ToString()));

                if (answer.Title.IsNotEmpty())
                {
                    entity.Answers.Add(answer);
                }
            }

            // remove
            foreach (var removeAnswerID in objectBinder.RemoveIDs
                                                       .OrderByDescending(i => i))
            {
                if (entity.Answers.Count > removeAnswerID && removeAnswerID >= 0)
                {
                    entity.Answers.RemoveAt(removeAnswerID);
                }
            }

            //sort
            var orderedList = entity.Answers.OrderBy(a => a.Position).ToList();
            entity.Answers.Clear();
            foreach (var answer in orderedList)
            {
                entity.Answers.Add(answer);
            }

            return true;
        }

        #endregion IQuestionFacade

        #region properties

        // NOTE: You MUST extend IQuestionFacade declaration this way:
        // IUserFacade UserFacade { set; }
        // to get injected instance (by the IocWithProxyFactory)

        // public virtual IUserFacade UserFacade { protected get; set; }

        #endregion properties

        //public bool CheckAnswersValidity(Question entity)
        //{
        //    if (!this.CheckIsNotEmpty(() => entity.Answers))
        //    {
        //        return false;
        //    }

        //    var result = true;
        //    foreach (var answer in entity.Answers)
        //    {
        //        result &= this.CheckLength(() => answer.Title, 1, 250);
        //        result &= this.CheckLength(() => answer.Description, 0, 2000);
        //    }
        //    return result;
        //}
    }
}